﻿using NET6.WebAPI.Entities.Base;
using NET6.WebAPI.Exceptions;
using SqlSugar;
using System.Linq.Expressions;
using static NET6.WebAPI.Entities.Base.BusinessBase;

namespace NET6.WebAPI.Extensions
{
    public static class BusinessExtension
    {
        /// <summary>
        /// 异步获取一条记录, 并检查记录是否存在
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="queryable"></param>
        /// <param name="whereExpression">查询条件委托</param>
        /// <returns></returns>
        public static async Task<T> GetFirstAsync<T>
            (this ISugarQueryable<T> queryable, Expression<Func<T, bool>> whereExpression)
        {
            var data = await queryable.FirstAsync(whereExpression);
            return data != null ? data : throw new NotExistsException();
        }

        /// <summary>
        /// 异步检查记录是否存在
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="queryable"></param>
        /// <param name="whereExpression">查询条件委托</param>
        /// <returns></returns>
        public static async Task CheckExistsAsync<T>
            (this ISugarQueryable<T> queryable, Expression<Func<T, bool>> whereExpression)
        {
            if (await queryable.Where(whereExpression).AnyAsync())
            {
                throw new NameDuplicateException();
            }
        }

        /// <summary>
        /// 异步逻辑删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="updateable"></param>
        /// <param name="id">主键值</param>
        /// <returns></returns>
        public static async Task<bool> LogicalDeleteAsync<T>
            (this IUpdateable<T> updateable, int? id) where T : BusinessBase, new()
        {
            if (id != null)
            {
                return await updateable.Where(it => it.ID == id).SetColumns(it => new T
                {
                    RecordStatus = RecordStatusEnum.Deleted,
                    DeleteTime = DateTime.Now,
                })
                .ExecuteCommandHasChangeAsync();
            }

            return false;
        }

        /// <summary>
        /// 异步逻辑恢复
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="updateable"></param>
        /// <param name="id">主键值</param>
        /// <returns></returns>
        public static async Task<bool> LogicalRecoverAsync<T>
            (this IUpdateable<T> updateable, int? id) where T : BusinessBase, new()
        {
            if (id != null)
            {
                return await updateable.Where(it => it.ID == id).SetColumns(it => new T
                {
                    RecordStatus = RecordStatusEnum.Active,
                    RecoverTime = DateTime.Now,
                })
                .ExecuteCommandHasChangeAsync();
            }

            return false;
        }
    }
}
